package com.jxzn.locust.utils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.Column;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

public final class ModelUtils {
    public static <K> Map<String, K> list2MapWithStringKey(List<K> modelList) {
        return list2MapWithStringKey(modelList, "id");
    }

    /**
     * 将给定的list集合转换为map，map的key=field，如果集合的元素不包含field字段，则返回空map.
     * 
     * @param modelList
     * @param field
     * @return
     */
    public static <K> Map<String, K> list2MapWithStringKey(List<K> modelList, String field) {
        Map<String, K> m = new HashMap<String, K>();
        if (null == modelList || modelList.isEmpty() || StringUtils.isBlank(field)) {
            return m;
        }
        for (K am : modelList) {
            Class<?> clazz = am.getClass();
            while (clazz != Object.class) {
                try {
                    Field f = clazz.getDeclaredField(field);
                    f.setAccessible(Boolean.TRUE);
                    try {
                        m.put(f.get(am).toString(), am);
                    } catch (Exception e) {
                    }
                    break;
                } catch (NoSuchFieldException e) {
                }
                clazz = clazz.getSuperclass();
            }

        }
        return m;
    }

    public static <T> T map2Bean(Map<String, Object> map, Class<T> clz) {
        try {
            T t = clz.newInstance();
            Field[] fields = clz.getDeclaredFields();
            fields = (Field[]) ArrayUtils.addAll(fields, clz.getSuperclass().getDeclaredFields());
            for (Field f : fields) {
                f.setAccessible(true);
                String fieldName = StringUtils.EMPTY;
                Column c = f.getAnnotation(Column.class);
                if (map.containsKey(f.getName())) {
                    fieldName = f.getName();
                } else if (null != c && map.containsKey(c.name())) {
                    fieldName = c.name();
                }
                if (StringUtils.isBlank(fieldName)) {
                    continue;
                }
                if (f.getType().isEnum()) {
                    Object value = map.get(fieldName);
                    Object[] os = f.getType().getEnumConstants();
                    for (Object o : os) {
                        if (o.toString().equals(value)) {
                            f.set(t, o);
                        }
                    }
                } else if (f.getType() == boolean.class) {
                    try {
                        int value = Integer.valueOf(map.get(fieldName).toString());
                        f.set(t, value == 1);
                    } catch (Exception e) {
                        f.set(t, map.get(fieldName));
                    }
                } else {
                    f.set(t, map.get(fieldName));
                }
            }
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static <T> List<T> listMap2BeanList(List<Map<String, Object>> mapList, Class<T> clz) {
        List<T> tList = new ArrayList<T>();
        for (Map<String, Object> map : mapList) {
            T t = map2Bean(map, clz);
            if (null != t) {
                tList.add(t);
            }
        }
        return tList;
    }
}
